package com.binarycube.webserver.wrappers;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

/**
 * Convenience wrapper around the {@link HttpServletRequest} 
 * @author chris
 *
 */
public class WrappedRequest extends Wrapper {
	static Logger log = Logger.getLogger(WrappedRequest.class.getName());

	HttpServletRequest _request;
	HashMap<String, Cookie> _cookies;
	List<FileItem> items = null;
	
	@SuppressWarnings("unchecked")
	public WrappedRequest(HttpServletRequest request){
		_request = request;
		//Build a lookup table for cookies
		_cookies = new HashMap<String, Cookie>();
		for (Cookie cookie:_request.getCookies()){
			_cookies.put(cookie.getName(), cookie);
		}
	
		
		//Process mulitpart.
		if (ServletFileUpload.isMultipartContent(_request)) {
			
			
			// Create a factory for disk-based file items
			DiskFileItemFactory factory = new DiskFileItemFactory();

			// Set factory constraints
			//factory.setSizeThreshold(yourMaxMemorySize);
			//factory.setRepository(yourTempDirectory);
			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);
			
			// Set overall request size constraint
			//upload.setSizeMax(yourMaxRequestSize);

			try {
				items = upload.parseRequest(request);
			} catch (FileUploadException e) {
				log.error("Problem loading attachments.",e);
			}
		}
					
	}
	

	public List<FileItem> getFieldFiles(String field) {
		if (items == null) return null;
		List<FileItem> tmp = new ArrayList<FileItem> ();
		for (FileItem fi : items) {
			if ((!fi.isFormField())&&(fi.getFieldName().equals(field))) tmp.add(fi);
		}
		return tmp;
	}
	
	
	public List<FileItem> getRequestFiles(){
		return items;
	}
	
	public String getCookieValue(String name) {
		Cookie tmp = _cookies.get(name);
		if (tmp != null) return tmp.getValue();
		return null;
	}
	
/* Parameter related goodness .. working of parsed params */
	
	public String getParameter(String name) {
		return _request.getParameter(name);
	}
	
	public String[] getParameterNames(){
		return _request.getParameterMap().keySet().toArray(new String[0]);
	}
	
	public String[] getParameterValues(String name) {
		return _request.getParameterValues(name);
	}
	
	
	public long getParameterValueAsLong(String name) {
		String tmp = getParameter(name);
		if (tmp != null) return Long.parseLong(tmp);
		return 0;
	}
	
	public int getParameterAsInteger(String name){
		String x = getParameter(name);
		if (x != null) return Integer.parseInt(x);
		return -1;
	}
	
	public UUID getParameterAsUUID(String name) {
		String x = getParameter(name);
		if (x != null) return UUID.fromString(name);
		return null;
	}
	
	
	public boolean hasParameter(String name) {
		return _request.getParameterMap().containsKey(name);
	}

	
	public String getMethod() {
		return _request.getMethod();
	}
	
    
    public String toString(){
		StringBuilder buffer = new StringBuilder("Parameters:");
		for (String key: _request.getParameterMap().keySet()){
			buffer.append(key).append(":").append(_request.getParameter(key)).append(",");
		}
		buffer.append("Cookies:");
		for (String key: _cookies.keySet()){
			buffer.append(key).append(":").append(_cookies.get(key)).append(",");
		}
		
		return buffer.toString();
	}


	public String getPath() {
		return _request.getPathTranslated();
	}


	public String getDomain() {
		return _request.getServerName();
	}


	public String getIP() {
		return _request.getRemoteAddr();
	}

	
}
